package com.command.center.pucms.pucmsgateway.freamwork.shiro;


import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.command.center.pucms.common.constant.Constant;
import com.command.center.pucms.common.util.ServletUtils;
import com.command.center.pucms.common.util.SimpleJwtUtil;
import com.command.center.pucms.pucmsgateway.domain.User;
import com.command.center.pucms.pucmsgateway.service.IUserService;
import com.command.platform.redis.template.RedisRepository;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author zlb
 * @since 2021-04-26
 */
@Slf4j
public class JwtRealm extends AuthorizingRealm {
    @Resource
    private IUserService userService;
    @Autowired
    private RedisRepository redisRepository;

    /**
     * 大坑！，必须重写此方法，不然Shiro会报错
     */
    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof JWTToken;
    }

    /**
     * 只有当需要检测用户权限的时候才会调用此方法，例如checkRole,checkPermission之类的
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        log.info("开始鉴权");
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        String token = principals.getPrimaryPrincipal().toString();
        String userName = SimpleJwtUtil.getUserName(token);
        List<String> roleList = JSONUtil.parseArray(redisRepository.get(userName + Constant.SEPARATOR + Constant.ROLES)).toList(String.class);
        List<String> permissionList = JSONUtil.parseArray(redisRepository.get(userName + Constant.SEPARATOR + Constant.PERMISSIONS)).toList(String.class);
        // 添加角色
        authorizationInfo.addRoles(roleList);
        // 添加权限
        authorizationInfo.addStringPermissions(permissionList);
        return authorizationInfo;
    }

    /**
     * 默认使用此方法进行用户名正确与否验证，错误抛出异常即可。
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {

        HttpServletRequest request = ServletUtils.getRequest();
        //获取token
        String token = (String) authenticationToken.getCredentials();
        //获取用户姓名
        String userName = SimpleJwtUtil.getUserName(token);
        if (userName == null) {
            throw new AuthenticationException("token invalid");
        }
        //根据用户名查询用户是否存在
        User user = userService.getOne(new QueryWrapper<User>().eq("name", userName));
        if (user == null) {
            throw new AuthenticationException("User didn't existed!");
        }

        return new SimpleAuthenticationInfo(token, token, this.getName());
    }


}
